package com.itheima;


import org.example.UserService;
import org.junit.jupiter.api.*;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

import java.time.LocalDate;

import static org.junit.jupiter.api.Assertions.*;

/**
 * UserService 类的单元测试
 */
public class userServiceTest3 {

    private UserService userService;

    @BeforeEach
    public void setUp() {
        userService = new UserService();
    }

    /**
     * 测试当传入 null 时抛出 IllegalArgumentException
     */
    @Test
    public void testGetAgeWithNullIdCardShouldThrowException() {
        IllegalArgumentException exception = assertThrows(
                IllegalArgumentException.class,
                () -> userService.getAge(null)
        );
        assertEquals("无效的身份证号码", exception.getMessage());
    }

    /**
     * 测试当传入非18位身份证号时抛出 IllegalArgumentException
     */
    @Test
    public void testGetAgeWithInvalidLengthIdCardShouldThrowException() {
        String invalidIdCard = "123456";
        IllegalArgumentException exception = assertThrows(
                IllegalArgumentException.class,
                () -> userService.getAge(invalidIdCard)
        );
        assertEquals("无效的身份证号码", exception.getMessage());
    }

    /**
     * 测试正常身份证号能正确计算年龄
     * 模拟 LocalDate.now() 返回固定时间以便测试
     */
    @Test
    public void testGetAgeWithValidIdCardShouldReturnCorrectAge() {
        // 假设身份证号为 110101199003072516，表示 1990年3月7日 出生
        String validIdCard = "110101199003072516";

        // 固定当前时间为 2023-04-01
        try (MockedStatic<LocalDate> mockedStatic = Mockito.mockStatic(LocalDate.class)) {
            mockedStatic.when(LocalDate::now).thenReturn(LocalDate.of(2023, 4, 1));

            Integer age = userService.getAge(validIdCard);

            assertEquals(33, age); // 2023 - 1990 = 33，且生日已过（3月 < 4月）
        }
    }

    /**
     * 测试在生日之后的时间点计算年龄是否正确
     */
    @Test
    public void testGetAgeWhenBirthdayHasPassedThisYear() {
        String validIdCard = "110101199003072516";

        try (MockedStatic<LocalDate> mockedStatic = Mockito.mockStatic(LocalDate.class)) {
            mockedStatic.when(LocalDate::now).thenReturn(LocalDate.of(2024, 3, 8));

            Integer age = userService.getAge(validIdCard);

            assertEquals(34, age); // 生日已经过了（3月8日 > 3月7日）
        }
    }

    /**
     * 测试在生日之前的时间点计算年龄是否正确
     */
    @Test
    public void testGetAgeWhenBirthdayNotYetThisYear() {
        String validIdCard = "110101199003072516";

        try (MockedStatic<LocalDate> mockedStatic = Mockito.mockStatic(LocalDate.class)) {
            mockedStatic.when(LocalDate::now).thenReturn(LocalDate.of(2024, 3, 6));

            Integer age = userService.getAge(validIdCard);

            assertEquals(33, age); // 生日还没到（3月6日 < 3月7日）
        }
    }
}
